package com.android.unipluginpicturewater;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.TimeUtils;
import android.util.TypedValue;

import androidx.core.app.NavUtils;

import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Description: UniPlugin-Hello-AS
 * Author:     yangtong<br>
 * Date:    2023/5/17    10:47
 * Version:
 * Update:
 */
public class WaterMaker {
    static String path;
    private File file;
    private int fileSize;
    private String base64String;
    private Context mContent;

    private int text_font;
    private int text_color;
    private String iconType;///point点 icon:图标 none：纯文字 默认
    //    旋转文字 默认是当前时间
    private String rotateStr;

    private final String TAG = "WaterMaker";
    private int x = 20;//横向间距
    private int topY;//上方纵向间距
    private int bottomy;//底部纵向间距
    private final int iconSpec = 10;//icon与文字间的间隙

    public WaterMaker(Context mContent) {
        this.mContent = mContent;
        this.text_color = Color.parseColor("#ffffff");
        this.text_font = 14;
        this.rotateStr = getStringTime(System.currentTimeMillis());
        this.iconType = "point";
    }

    //    配置项
    private void configSeting(JSONObject options) {
        if (options.containsKey("textColor") && options.getString("textColor") != null) {
            text_color = Color.parseColor(options.getString("textColor"));
        }
        if (options.containsKey("fontSize") && options.getString("fontSize") != null) {
            text_font = options.getInteger("fontSize");
        }
        if (options.containsKey("decorate") && options.getString("decorate") != null) {
            this.iconType = options.getString("decorate");
        }
        if (options.containsKey("topY") && options.getIntValue("topY") > 0) {
            topY = options.getIntValue("topY");
        } else {
            topY = 50;
        }
        if (options.containsKey("bottomY") && options.getIntValue("bottomY") > 0) {
            bottomy = options.getIntValue("bottomY");
        } else {
            bottomy = 20;
        }
    }

    private String getStringTime(Long time) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public void waterMarkBitmap(JSONObject options, String scr, boolean base64, List<JSONObject> contents, boolean hasMark, int positionType, String rotateText,float compressSize) {
        if (options != null) {
            configSeting(options);
        }
//斜体文字
        if (rotateText != null && !TextUtils.isEmpty(rotateText)) {
            rotateStr = rotateText;
        }
        Bitmap bit = null;
        if (base64) {
            bit = base64ToBitMap(scr);
            Log.d(TAG, "waterMarkBitmap: "+bit);
        } else {
            bit = BitmapUtil.pathToBitmap(scr);
        }
        if (bit == null) {
            return;
        }
//        先绘制contents
        int w = bit.getWidth();
        int h = bit.getHeight();
//        创建一个新的和SRC长度宽度一样的位图
        Bitmap newMap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas cn = new Canvas(newMap);
        cn.drawBitmap(bit, 0, 0, null);
        cn.save();
        cn.restore();
        if (hasMark) {
            newMap = getMarkTextBitmap(mContent, w, h, true, newMap);
            cn.save();
        }
        int bottomY = h - bottomy;
        TextPaint textPaint = new TextPaint();
        String familyName = "宋体";
        Typeface font = Typeface.create(familyName, Typeface.NORMAL);
        textPaint.setColor(text_color);
        textPaint.setTypeface(font);
        textPaint.setTextSize(sp2px(text_font));
//        文字最大宽度
        int textMaxWidth = w - 2 * x;
        for (int i = 0; i < contents.size(); i++) {
            JSONObject object = contents.get(i);
            Bitmap iconBit = null;
            if (iconType.equals("point")) {
                object.put("text", "• " + object.getString("text"));
            } else if (iconType.equals("icon")) {
                iconBit = BitmapUtil.pathToBitmap(object.getString("icon"));
                textMaxWidth = textMaxWidth - iconBit.getWidth();
            }
            float textWidth = getFontWidth(object.getString("text"), textPaint);
            StaticLayout layout = new StaticLayout(object.getString("text"), textPaint, w - 2 * x, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
            if (positionType == 0) {//左上
                if (iconBit != null) {
                    cn.drawBitmap(iconBit, x, topY, null);
                    newMap = textWrap(newMap, textPaint, object.getString("text"), x + iconBit.getWidth() + iconSpec, topY, iconBit.getWidth() + iconSpec);
                } else {
                    newMap = textWrap(newMap, textPaint, object.getString("text"), x, topY, 0);
                }
                topY += (layout.getHeight());
            } else if (positionType == 1) {//右上
                int positionX = w - x - layout.getWidth();
                if (iconBit != null) {
                    layout = new StaticLayout(object.getString("text"), textPaint, w - 2 * x - iconSpec - iconBit.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
                    if (textWidth < w - 2 * x - iconBit.getWidth() - iconSpec) {
                        positionX = (int) (w - x - textWidth - iconBit.getWidth() - iconSpec);
                    } else {
                        positionX = x;
                    }
                    cn.drawBitmap(iconBit, positionX, topY, null);
                    newMap = textWrap(newMap, textPaint, object.getString("text"), positionX + iconSpec + iconBit.getWidth(), topY, iconSpec + iconBit.getWidth());
                } else {
                    if (textWidth < w - 2 * x) {
                        positionX = (int) (w - x - textWidth);
                    }
                    newMap = textWrap(newMap, textPaint, object.getString("text"), positionX, topY, 0);
                }
                topY += (layout.getHeight());
            } else if (positionType == 2) {//左下
                if (iconBit != null) {
                    cn.drawBitmap(iconBit, x, bottomY - layout.getHeight() + 3, null);
                    newMap = textWrap(newMap, textPaint, object.getString("text"), x + iconBit.getWidth() + iconSpec, bottomY - layout.getHeight(), iconBit.getWidth() + iconSpec);
                } else {
                    newMap = textWrap(newMap, textPaint, object.getString("text"), x, bottomY - layout.getHeight(), 0);
                }
                bottomY -= layout.getHeight();
            } else if (positionType == 3) {//右下
                int positionX = w - x - layout.getWidth();
                if (iconBit != null) {
                    layout = new StaticLayout(object.getString("text"), textPaint, w - 2 * x - iconSpec - iconBit.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
                    if (textWidth < w - 2 * x - iconBit.getWidth() - iconSpec) {
                        positionX = (int) (w - x - textWidth - iconBit.getWidth() - iconSpec);
                    } else {
                        positionX = x;
                    }
                    cn.drawBitmap(iconBit, positionX, bottomY - layout.getHeight() + 3, null);
                    newMap = textWrap(newMap, textPaint, object.getString("text"), positionX + iconSpec + iconBit.getWidth(), bottomY - layout.getHeight(), iconSpec + iconBit.getWidth());
                } else {
                    if (textWidth < w - 2 * x) {
                        positionX = (int) (w - x - textWidth);
                    }
                    newMap = textWrap(newMap, textPaint, object.getString("text"), positionX, bottomY - layout.getHeight(), 0);
                }
                bottomY -= layout.getHeight();
            }
            cn = new Canvas(newMap);
            cn.save();
        }
        cn.restore();
        file = CompressUtils.compressImage(newMap, compressSize*1024);
        fileSize = (int) file.length()/1024;
        path = file.getPath();
        base64String = file2Base64(path);
        if (bit != null) {
            bit.recycle();
            bit = null;
        }
        if (newMap != null) {
            newMap.recycle();
            newMap = null;
        }

        System.gc();
    }

    //    base64转bitmap
    private Bitmap base64ToBitMap(String base64Str) {
        String data = null;
        if (base64Str.contains(",")){
            data = base64Str.split(",")[1];
        }
        Bitmap bitmap = null;
        try {
            byte[] bitBase64 = Base64.decode(data, Base64.DEFAULT);
            bitmap = BitmapFactory.decodeByteArray(bitBase64, 0, bitBase64.length);
            return bitmap;
        }catch (Exception e){
            e.printStackTrace();
        }
        return bitmap;
    }

    // bitmap 转Base64
    private String file2Base64(String pathStr) {
        if (TextUtils.isEmpty(pathStr)){
            return "";
        }
        InputStream is = null;
        byte[] data = null;
        String resule= null;
        try {
            is = new FileInputStream(pathStr);
            data = new byte[is.available()];
            is.read(data);
            resule = Base64.encodeToString(data,Base64.DEFAULT);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resule;
    }

    public File getFile() {
        return file;
    }

    public String getPath() {
        return path;
    }

    public String getBase64String() {
        return base64String;
    }

    public int getFileSize() {
        return fileSize;
    }

    //    dp2px
    private int dp2px(float dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, mContent.getResources().getDisplayMetrics());
    }

    //    sp2px
    private int sp2px(int spValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, (float) spValue, mContent.getResources().getDisplayMetrics());
    }

    private float getFontWidth(String text, TextPaint paint) {
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        int width = bounds.width();
        return width;
    }

    //斜体
    private Bitmap getMarkTextBitmap(Context gContext, int width, int height, boolean is4Showing, Bitmap bitmap) {
        String gText = rotateStr;
        float textSize;
        float inter;
        if (is4Showing) {
            textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, text_font, gContext.getResources().getDisplayMetrics());
            inter = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 75, gContext.getResources().getDisplayMetrics());
        } else {
            textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 54, gContext.getResources().getDisplayMetrics());
            inter = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 75, gContext.getResources().getDisplayMetrics());
        }

        int sideLength;
        if (width > height) {
            sideLength = (int) Math.sqrt(2 * (width * width));
        } else {
            sideLength = (int) Math.sqrt(2 * (height * height));
        }


        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Rect rect = new Rect();
        paint.setTextSize(textSize);
        //获取文字长度和宽度
        paint.getTextBounds(gText, 0, gText.length(), rect);

        int strwid = rect.width();
        int strhei = rect.height();

        Bitmap markBitmap = null;
        try {
            markBitmap = bitmap;
            Canvas canvas = new Canvas(markBitmap);
            //创建透明画布
            canvas.drawColor(Color.TRANSPARENT);
            paint.setColor(text_color);
            paint.setAlpha((int) (0.3 * 255f));
            // 获取跟-清晰的图像采样
            paint.setDither(true);
            paint.setFilterBitmap(true);

            //先平移，再旋转才不会有空白，使整个图片充满
            if (width > height) {
                canvas.translate(sideLength + inter - width, width - inter - sideLength);
            } else {
                canvas.translate(sideLength + inter - height, height - inter - sideLength);
            }

            //将该文字图片逆时针方向倾斜45度
            canvas.rotate(45);

            for (int i = 0; i <= sideLength; ) {
                int count = 0;
                for (int j = 0; j <= sideLength; count++) {
                    if (count % 2 == 0) {
                        canvas.drawText(gText, i, j, paint);
                    } else {
                        //偶数行进行错开
                        canvas.drawText(gText, i + strwid / 2, j, paint);
                    }
                    j = (int) (j + inter + strhei);
                }
                i = (int) (i + strwid + inter);
            }
            canvas.save();
        } catch (OutOfMemoryError e) {
            if (markBitmap != null && !markBitmap.isRecycled()) {
                markBitmap.recycle();
                markBitmap = null;
            }
        }

        return markBitmap;
    }

    //    文字换行
    private Bitmap textWrap(Bitmap newMap, TextPaint textPaint, String text, int x1, int topY, int iconSpec) {
        //        先绘制contents
        int w = newMap.getWidth();
        int h = newMap.getHeight();
//        创建一个新的和SRC长度宽度一样的位图
        Bitmap newMap1 = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas cn = new Canvas(newMap1);
        cn.drawBitmap(newMap, 0, 0, null);
        StaticLayout layout = null;
        if (iconType.equals("icon")) {
            layout = new StaticLayout(text, textPaint, w - 2 * x - iconSpec, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
        } else {
            layout = new StaticLayout(text, textPaint, w - 2 * x, Layout.Alignment.ALIGN_NORMAL, 1.0F, 0.0F, true);
        }
        cn.translate(x1, topY);
        layout.draw(cn);
        cn.save();
        return newMap1;
    }
}
